const obj = {
  "count": 2,
  "price": 10,
  "totalPrice": 20,
  "desc": '太贵了'
}

class Goods {
  constructor(obj) {
    Object.assign(this, obj) // 当前类的一些属性值的复制

    // 对count属性进行细化处理
    let count = this.count;
    Object.defineProperty(this, 'count', {
      // 禁止当前类的count属性修改 
      // writable: false,
      // 重写get set方法，进行一些提示处理
      get: function() {
        return count;
      },
      set: function(val) {
        // 不允许修改count属性
        throw new Error("count属性不允许修改！")
        // count = val;
      }
    })

    // 对price属性进行限制
    let price = this.price;
    Object.defineProperty(this, 'price', {
      get: function(){
        return price
      },
      set: function(val){
        if(typeof val !== 'number') {
          throw new Error('price必须为一个数字');
        } else {
          price = val;
        }
      }
    })

    // 对totalPrice属性做一个限制
    Object.defineProperty(this, 'totalPrice', {
      get: function() {
        return this.count * this.price;
      }
    })
    
    // 对desc属性做一个限制
    Object.defineProperty(this, 'desc', {
      enumerable: false,
      writable: false,
      configurable: false
    })
  }
}

const good = new Goods(obj);

console.log(good.count); // 输出 2
console.log(good.totalPrice); // 输出 20

try {
  good.count = 5; // 抛出错误：count属性不允许修改！
} catch (error) {
  console.error(error.message);
}

try {
  good.price = '贵'; // 抛出错误：price必须为一个数字
} catch (error) {
  console.error(error.message);
}

console.log(good.totalPrice); // 输出 20

// 遍历属性时，desc 不会被列举
console.log(Object.keys(good)); // 输出 [ 'count', 'price', 'totalPrice' ]

console.log(good.desc); // '太贵了', 但不能修改